﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
using System.Net.Sockets;
using System.Net;

namespace StartExamples
{
    internal static class Program
    {
        [STAThread]
        private static void Main(string[] args)
        {
            string currentDirectory = Environment.CurrentDirectory;
            string appName = "";
            ProcessParameters(args, ref currentDirectory, ref appName);

            string devServerExecutable = GetDevServerExecutable(CheckQsf40(currentDirectory));
            string portNumber = GetPortNumber();

            if (!File.Exists(devServerExecutable)){
                Console.WriteLine("Cannot find the ASP.NET Development Server!");
            }else{
                StartProcess(devServerExecutable, portNumber, currentDirectory, appName);
            }
        }
        private static void ProcessParameters(string[] args, ref string physPath, ref string appName)
        {
            foreach (string str in args)
            {
                if (str.StartsWith("-path:", StringComparison.OrdinalIgnoreCase))
                {
                    physPath = str.Remove(0, 6);
                }
                else if (str.StartsWith("-appname:", StringComparison.OrdinalIgnoreCase))
                {
                    appName = str.Remove(0, 9);
                }
                else if (str.StartsWith("-help", StringComparison.OrdinalIgnoreCase) || str.StartsWith("-?", StringComparison.OrdinalIgnoreCase))
                {
                    ShowHelp();
                }
            }
        }
        private static void ShowHelp()
        {
            MessageBox.Show("Usage: {0} [-path:<path to root of web>] [-appname:/<name of web application>]", 
                Application.ExecutablePath.Substring(Application.ExecutablePath.LastIndexOf(@"\") + 1));
        }
        private static string GetDevServerExecutable(bool check40)
        {
            string str = string.Empty;
            string path = string.Empty;
            if (check40)
            {
                path = string.Format(@"{0}\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.exe", Environment.GetEnvironmentVariable("CommonProgramFiles"));
                if (File.Exists(path)){
                    str = path;
                }else{
                    path = string.Format(@"{0}\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.exe", Environment.GetEnvironmentVariable("CommonProgramFiles(x86)"));
                    if (File.Exists(path)){
                        str = path;
                    }
                }
            }
            if (str.Length == 0){
                path = string.Format(@"{0}\Microsoft Shared\DevServer\10.0\WebDev.WebServer20.exe", Environment.GetEnvironmentVariable("CommonProgramFiles"));
                if (File.Exists(path)){
                    str = path;
                }else{
                    path = string.Format(@"{0}\Microsoft Shared\DevServer\10.0\WebDev.WebServer20.exe", Environment.GetEnvironmentVariable("CommonProgramFiles(x86)"));
                    if (File.Exists(path)){
                        str = path;
                    }
                }
            }
            if (str.Length == 0){
                path = string.Format(@"{0}\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe", Environment.GetEnvironmentVariable("CommonProgramFiles"));
                if (File.Exists(path)){
                    str = path;
                }else{
                    path = string.Format(@"{0}\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe", Environment.GetEnvironmentVariable("CommonProgramFiles(x86)"));
                    if (File.Exists(path)){
                        str = path;
                    }
                }
            }
            if (str.Length != 0){
                return str;
            }
            string str3 = "50727";
            RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\policy\v2.0");
            if ((key != null) && (key.ValueCount > 0)){
                str3 = key.GetValueNames()[0];
            }else{
                MessageBox.Show("Error while reading .NET Framework 2.0 configuration! Assuming default values.");
            }
            return string.Format(@"{0}\Microsoft.NET\Framework\v2.0.{1}\WebDev.WebServer.exe", Environment.GetEnvironmentVariable("WINDIR"), str3);
        }
        private static bool CheckQsf40(string physPath)
        {
            string path = physPath + @"\Web.Config";
            if (File.Exists(path)){
                StreamReader reader = new StreamReader(path);
                string str2 = reader.ReadToEnd();
                reader.Close();
                return (str2.IndexOf("System.Data.Linq, Version=4.0.0.0") != -1);
            }
            return false;
        }
        private static string GetPortNumber()
        {
            bool flag = false;
            TcpListener listener = null;
            int port = 0;
            try
            {
                listener = new TcpListener(IPAddress.Any, 0x206d);
                listener.ExclusiveAddressUse = true;
                listener.Start();
                port = ((IPEndPoint)listener.LocalEndpoint).Port;
                listener.Stop();
            }
            catch (SocketException)
            {
                flag = true;
            }
            if (flag)
            {
                try
                {
                    listener = new TcpListener(IPAddress.Any, 0);
                    listener.Start();
                    port = ((IPEndPoint)listener.LocalEndpoint).Port;
                    listener.Stop();
                }
                catch (Exception)
                {
                }
            }
            if (port == 0)
            {
                port = 0x206d;
            }
            return port.ToString();
        }
        private static void StartProcess(string cassiniExecutable, string portNumber, string physPath, string appName)
        {
            Process process = new Process();
            process.StartInfo.FileName = cassiniExecutable;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.StartInfo.Arguments = string.Format("/port:{0} /path:\"{1}\" /vpath:\"{2}\"", portNumber, physPath, appName);
            process.Start();
            new WaitMessageForm().ShowDialog();
            Process process2 = new Process();
            process2.StartInfo.UseShellExecute = true;
            process2.StartInfo.FileName = string.Format("http://localhost:{0}{1}", portNumber, appName);
            process2.Start();
        }
    }
}
